package com.xyht.sca_s.student_manage_system.modules.asset.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.common.util.CacheUtil;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetProcess;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.SmsAssetProcessDetail;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.req.SmsAssetProcessDetailDeleteReq;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.req.SmsAssetProcessDetailReq;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.resp.SmsAssetOriginProcessDetailResp;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.resp.SmsAssetProcessDetailResp;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.resp.SmsAssetProcessObjectResp;
import com.xyht.sca_s.student_manage_system.modules.asset.entity.resp.SmsAssetProcessResp;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetProcessDetailMapper;
import com.xyht.sca_s.student_manage_system.modules.asset.mapper.SmsAssetProcessMapper;
import com.xyht.sca_s.student_manage_system.modules.asset.service.SmsAssetProcessService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsRole;
import com.xyht.sca_s.student_manage_system.modules.user.entity.SmsUser;
import com.xyht.sca_s.student_manage_system.modules.user.mapper.SmsRoleMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.AssetBooleanConstant.ASSET_BOOLEAN_FALSE;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.AssetBooleanConstant.ASSET_BOOLEAN_TRUE;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.ProcessDetailIsUseConstant.PROCESS_DETAIL_CLOSE;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.ProcessDetailIsUseConstant.PROCESS_DETAIL_OPEN;
import static com.xyht.sca_s.student_manage_system.modules.asset.constant.ProcessObjectTypeConstant.PROCESS_OBJECT_TYPE_PERSON;

/**
 * <p>
 * 资产管理流程管理 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2023-05-12
 */
@Service
public class SmsAssetProcessServiceImpl extends ServiceImpl<SmsAssetProcessMapper, SmsAssetProcess> implements SmsAssetProcessService {
    @Autowired
    private SmsAssetProcessMapper smsAssetProcessMapper;
    @Autowired
    private SmsAssetProcessDetailMapper smsAssetProcessDetailMapper;
    @Autowired
    private CacheUtil cacheUtil;
    @Autowired
    private SmsRoleMapper smsRoleMapper;


    @Override
    public ResponseResult addProcessDetail(SmsAssetProcessDetailReq smsAssetProcessDetailReq) {
        SmsAssetProcess smsAssetProcess = smsAssetProcessMapper.selectById(smsAssetProcessDetailReq.getProcessId());
        if (smsAssetProcess == null || isNullOrEmpty(smsAssetProcess.getId())) {
            return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_NOT_EXIST);
        }

        if (smsAssetProcessDetailReq.getProcessDetailObjectType() == PROCESS_OBJECT_TYPE_PERSON) {
            SmsUser smsUser = cacheUtil.getUserInfo(smsAssetProcessDetailReq.getProcessDetailObjectId());
            if (smsUser == null) {
                return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_USER_NOT_EXIST);
            }
        } else {
            SmsRole smsRole = smsRoleMapper.selectById(smsAssetProcessDetailReq.getProcessDetailObjectId());
            if (smsRole == null || isNullOrEmpty(smsRole.getId())) {
                return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_ROLE_NOT_EXIST);
            }
        }

        Integer count = smsAssetProcessDetailMapper.selectCount(new QueryWrapper<SmsAssetProcessDetail>()
                .lambda()
                .eq(SmsAssetProcessDetail::getProcessId, smsAssetProcessDetailReq.getProcessId()));

        SmsAssetProcessDetail addProcessDetail = new SmsAssetProcessDetail();
        BeanUtils.copyProperties(smsAssetProcessDetailReq, addProcessDetail);
        addProcessDetail.setProcessDetailSort(count + 1);

        smsAssetProcessDetailMapper.insert(addProcessDetail);
        return CommonResult.success();
    }

    @Override
    public ResponseResult updateProcessDetail(SmsAssetProcessDetailReq smsAssetProcessDetailReq) {
        if (isNullOrEmpty(smsAssetProcessDetailReq.getDetailId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsAssetProcess smsAssetProcess = smsAssetProcessMapper.selectById(smsAssetProcessDetailReq.getProcessId());
        if (smsAssetProcess == null || isNullOrEmpty(smsAssetProcess.getId())) {
            return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_NOT_EXIST);
        }

        SmsAssetProcessDetail smsAssetProcessDetail = smsAssetProcessDetailMapper.selectById(smsAssetProcessDetailReq.getDetailId());
        if (smsAssetProcessDetail == null || isNullOrEmpty(smsAssetProcessDetail.getId())) {
            return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_DETAIL_NOT_EXIST);
        }

        if (smsAssetProcessDetailReq.getProcessDetailObjectType() == PROCESS_OBJECT_TYPE_PERSON) {
            if (smsAssetProcessDetailReq.getProcessDetailIsApplicantEdit() == ASSET_BOOLEAN_FALSE){
                if (isNullOrEmpty(smsAssetProcessDetailReq.getProcessDetailObjectId())){
                    return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
                }
                SmsUser smsUser = cacheUtil.getUserInfo(smsAssetProcessDetailReq.getProcessDetailObjectId());
                if (smsUser == null) {
                    return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_USER_NOT_EXIST);
                }
            }
        } else {
            SmsRole smsRole = smsRoleMapper.selectById(smsAssetProcessDetailReq.getProcessDetailObjectId());
            if (smsRole == null || isNullOrEmpty(smsRole.getId())) {
                return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_ROLE_NOT_EXIST);
            }
        }

        //判断是否关闭全部节点
//        if (smsAssetProcessDetailReq.getProcessDetailIsUse() == PROCESS_DETAIL_CLOSE) {
//            Integer openDetailCount = smsAssetProcessDetailMapper.selectCount(new QueryWrapper<SmsAssetProcessDetail>()
//                    .lambda()
//                    .eq(SmsAssetProcessDetail::getProcessId, smsAssetProcessDetailReq.getProcessId())
//                    .ne(SmsAssetProcessDetail::getId, smsAssetProcessDetailReq.getDetailId())
//                    .eq(SmsAssetProcessDetail::getProcessDetailIsUse, PROCESS_DETAIL_OPEN));
//            if (openDetailCount == 0){
//                return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_DETAIL_CLOSE_FAIL);
//            }
//        }

        SmsAssetProcessDetail updateProcessDetail = new SmsAssetProcessDetail();
        BeanUtils.copyProperties(smsAssetProcessDetailReq, updateProcessDetail);
        updateProcessDetail.setId(smsAssetProcessDetailReq.getDetailId());
        smsAssetProcessDetailMapper.updateById(updateProcessDetail);
        return CommonResult.success();
    }

    @Override
    public ResponseResult deleteProcessDetail(SmsAssetProcessDetailDeleteReq processDetailDeleteReq) {
        if (isNullOrEmpty(processDetailDeleteReq.getDetailId())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsAssetProcessDetail smsAssetProcessDetail = smsAssetProcessDetailMapper.selectById(processDetailDeleteReq.getDetailId());
        if (smsAssetProcessDetail == null || isNullOrEmpty(smsAssetProcessDetail.getId())) {
            return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_DETAIL_NOT_EXIST);
        }

        Integer count = smsAssetProcessDetailMapper.selectCount(new QueryWrapper<SmsAssetProcessDetail>()
                .lambda()
                .eq(SmsAssetProcessDetail::getProcessId, smsAssetProcessDetail.getProcessId()));

        if (!smsAssetProcessDetail.getProcessDetailSort().equals(count)){
            return CommonResult.failed(CommonCodeEnum.ASSET_PROCESS_DETAIL_DELETE_FAIL);
        }

        smsAssetProcessDetailMapper.deleteById(processDetailDeleteReq.getDetailId());
        return CommonResult.success();
    }

    @Override
    public ResponseResult getProcessList(Integer pageNum, Integer pageSize) {
        Page<SmsAssetProcess> page = new Page<>(pageNum, pageSize);
        smsAssetProcessMapper.selectPage(page, new QueryWrapper<SmsAssetProcess>()
                .lambda()
                .orderByAsc(SmsAssetProcess::getProcessType));
        List<SmsAssetProcessResp> respList = page.getRecords()
                .stream()
                .map(process -> {
                    SmsAssetProcessResp smsAssetProcessResp = new SmsAssetProcessResp();
                    BeanUtils.copyProperties(process, smsAssetProcessResp);
                    return smsAssetProcessResp;
                })
                .collect(Collectors.toList());
        int total = (int) page.getTotal();
        return CommonResult.success(respList, total);
    }

    @Override
    public ResponseResult getProcessDetailList(String process_id) {
        List<SmsAssetProcessDetailResp> respList = smsAssetProcessDetailMapper.selectList(new QueryWrapper<SmsAssetProcessDetail>()
                .lambda()
                .eq(SmsAssetProcessDetail::getProcessId, process_id))
                .stream()
                .map(detail->{
                    SmsAssetProcessDetailResp detailResp = new SmsAssetProcessDetailResp();
                    BeanUtils.copyProperties(detail,detailResp);

                    SmsAssetProcessObjectResp objectResp = new SmsAssetProcessObjectResp();
                    if (detailResp.getProcessDetailObjectType() == PROCESS_OBJECT_TYPE_PERSON){
                        SmsUser smsUser = cacheUtil.getUserInfo(detailResp.getProcessDetailObjectId());
                        if (smsUser != null) {
                            objectResp.setId(smsUser.getId());
                            objectResp.setObjectName(smsUser.getRealName());
                            objectResp.setObjectPic(smsUser.getUserPic());
                        }
                    } else {
                        SmsRole smsRole = smsRoleMapper.selectById(detailResp.getProcessDetailObjectId());
                        if (smsRole != null && !isNullOrEmpty(smsRole.getId())) {
                            objectResp.setId(smsRole.getId());
                            objectResp.setObjectName(smsRole.getRoleName());
                        }
                    }
                    detailResp.setObjectResp(objectResp);
                    return detailResp;
                })
                .collect(Collectors.toList());
        return CommonResult.success(respList);
    }

    @Override
    public ResponseResult getApplyOriginSettingProcess(Integer process_type) {
        SmsAssetProcess smsAssetProcess = smsAssetProcessMapper.selectOne(new QueryWrapper<SmsAssetProcess>()
                .lambda()
                .eq(SmsAssetProcess::getProcessType, process_type));

        List<SmsAssetOriginProcessDetailResp> respList =
                smsAssetProcessDetailMapper.selectList(new QueryWrapper<SmsAssetProcessDetail>()
                        .lambda()
                        .eq(SmsAssetProcessDetail::getProcessId, smsAssetProcess.getId())
                        .eq(SmsAssetProcessDetail::getProcessDetailIsApplicantEdit, true)
                        .eq(SmsAssetProcessDetail::getProcessDetailIsUse, true)
                        .orderByAsc(SmsAssetProcessDetail::getProcessDetailSort))
                        .stream()
                        .map(process -> {
                            SmsAssetOriginProcessDetailResp smsAssetOriginProcessDetailResp =
                                    new SmsAssetOriginProcessDetailResp();
                            BeanUtils.copyProperties(process, smsAssetOriginProcessDetailResp);
                            return smsAssetOriginProcessDetailResp;
                        })
                        .collect(Collectors.toList());
        return CommonResult.success(respList);
    }
}
